/*
 * semaphore.c
 * projet Unix: 6 qui prend
 *
 *  @authors Doublier Sami
 *  @authors Pingot Alexandre
 */

#include "semaphore.h"

int semInit(key_t key, int size) {
	int semid;
	int err;

	/* structure utilisée pour semctl */
	union semun {
		int val;
		struct semid_ds* buf;
		ushort* array;
	} arg;

	/* création de 3 semaphores
	 * car les sémaphores utilisees ont le numéro 1 et 2
	 * et que le compteur de sémaphores commence à 0 */
	if ((semid = semget(key, 3, IPC_CREAT | 0666)) < 0) {
		fprintf(stderr,
				"Erreur lors de la création des sémaphores %d\n",
				semid);
		return EXIT_FAILURE;
	}

	/* Initialisation des sémaphores */
	/* affectation de la valeur 0 au semaphore 0 */
	arg.val = size;
	if ((err = semctl(semid, MUTEX, SETVAL, arg)) < 0) {
		fprintf(stderr, "Erreur lors de l'affectation de la valeur 0 au sémaphore 0\n");
		return EXIT_FAILURE;
	}

	/* affectation de la valeur maximale de la zone
	 * partagée au semaphore 1
	 */

	if ((err = semctl(semid, DB, SETVAL, arg)) < 0) {
		fprintf(stderr, "Erreur lors de l'affectation de la valeur maximale au sémaphore 1\n");
		return EXIT_FAILURE;
	}

	return semid;
}

/******************************************************************************/

void semUp(int semid, int num) {
	struct sembuf sb;
	int err;

	sb.sem_num = num;
	sb.sem_op = 1;
	sb.sem_flg = 0;
	err = semop(semid, &sb, 1);

	if (err < 0)
		fprintf(stderr, "Erreur lors de l'incrémentation du semid: %d avec le code de l'erreur: %d\n", semid, err);
}

/******************************************************************************/

void semDown(int semid, int num) {
	struct sembuf sb;
	int err;

	sb.sem_num = num;
	sb.sem_op = -1;
	sb.sem_flg = 0;
	err = semop(semid, &sb, 1);

	if (err < 0)
		fprintf(stderr, "Erreur lors de la décrémentation du semid: %d avec le code de l'erreur: %d\n", semid, err);
}


